package org.yunai.protobuf.conf;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 项目配置
 * User: yunai
 * Date: 13-3-12
 * Time: 下午10:30
 */
public class ProjectConfig {

    private static final String CONFIG_ROOT = "ProjectConfig";
    private static final String CONFIG_ATTRIBUTE_NAME = "name";
    private static final String CONFIG_ATTRIBUTE_DESC = "desc";

    private static final String SIDE_ROOT = "Side";
    private static final String SIDE_ATTRIBUTE_NAME = "name";
    private static final String SIDE_ATTRIBUTE_LANG = "lang";
    private static final String SIDE_ATTRIBUTE_DESC = "desc";
    private static final String SIDE_ATTRIBUTE_SRC_PATH = "srcPath";
    private static final String SIDE_ATTRIBUTE_PACK = "pack";

    /**
     * 名称
     */
    public static String name;
    /**
     * 描述
     */
    public static String desc;
    /**
     * 端数组
     */
    public static List<Side> sides;

    /**
     * 端<br />
     * 比如: 客户端、服务端...
     */
    public static class Side {
        /**
         * 标识
         */
        private String name;
        /**
         * 语言
         */
        private String lang;
        /**
         * 描述
         */
        private String desc;
        /**
         * 项目路径
         */
        private String srcPath;
        /**
         * 包路径
         */
        private String pack;

        public Side(String name, String lang, String desc, String srcPath, String pack) {
            this.name = name;
            this.lang = lang;
            this.desc = desc;
            this.srcPath = srcPath;
            this.pack = pack;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLang() {
            return lang;
        }

        public void setLang(String lang) {
            this.lang = lang;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        public String getSrcPath() {
            return srcPath;
        }

        public void setSrcPath(String srcPath) {
            this.srcPath = srcPath;
        }

        public String getPack() {
            return pack;
        }

        public void setPack(String pack) {
            this.pack = pack;
        }
    }

    public static void load() {
        InputStream is = null;
        try {
            // 创建InputStream
            URL url = Thread.currentThread().getContextClassLoader().getResource(Config.filePath);
            if (url == null) {
                throw new FileNotFoundException(url + "文件不存在！");
            }
            is = new FileInputStream(url.getFile());

            // XML解析
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document doc = builder.parse(is);

            // 解析ProjectConfig节点
            NodeList projectConfigNodes = doc.getElementsByTagName(CONFIG_ROOT);
            if (projectConfigNodes.getLength() > 1) {
                throw new SAXException("<" + CONFIG_ROOT + ">只允许有一个！");
            }
            Node projectConfigNode = projectConfigNodes.item(0);
            parseProjectConfigNode(projectConfigNode);

            // 解析Side节点
            ProjectConfig.sides = new ArrayList<Side>();
            NodeList sideNodes = projectConfigNode.getChildNodes();
            for (int i = 0, len = sideNodes.getLength(); i < len; i++) {
                Node sideNode = sideNodes.item(i);
                if (!SIDE_ROOT.equals(sideNode.getNodeName())) {
                    continue;
                }
                parseSideNode(sideNode);
            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void parseProjectConfigNode(Node node) throws SAXException {
        NamedNodeMap projectConfigAttrs = node.getAttributes();
        ProjectConfig.name = projectConfigAttrs.getNamedItem(CONFIG_ATTRIBUTE_NAME).getNodeValue();
        ProjectConfig.desc = projectConfigAttrs.getNamedItem(CONFIG_ATTRIBUTE_DESC).getNodeValue();
    }

    private static void parseSideNode(Node node) {
        NamedNodeMap sideNodeAttrs = node.getAttributes();
        ProjectConfig.sides.add(new Side(
                sideNodeAttrs.getNamedItem(SIDE_ATTRIBUTE_NAME).getNodeValue(),
                sideNodeAttrs.getNamedItem(SIDE_ATTRIBUTE_LANG).getNodeValue(),
                sideNodeAttrs.getNamedItem(SIDE_ATTRIBUTE_DESC).getNodeValue(),
                sideNodeAttrs.getNamedItem(SIDE_ATTRIBUTE_SRC_PATH).getNodeValue(),
                sideNodeAttrs.getNamedItem(SIDE_ATTRIBUTE_PACK).getNodeValue()
        ));
    }
}
